﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using TCC_Hotel.Entidades;
using System.Globalization;
using System.Data.SqlClient;
using System.Configuration;

namespace TCC_Hotel.Repositorio
{
    public class ProdutoRepositorio
    {
        ControleBancoDados controle = new ControleBancoDados();

        /// <summary>
        /// Cria o comando SQL e envia para um método inserir um novo produto nos bancos de dados
        /// </summary>
        /// <param name="produto">Entidade produto</param>
        /// <returns>true se inseriu ou false se não</returns>
        public bool CadastrarProduto(Produto produto)
        {
            
            string precoVenda = produto.PrecoVenda.ToString(CultureInfo.InvariantCulture);

            //definição do comando sql
            string sql =
                "INSERT INTO Produtos_Estoque VALUES ('" +
                produto.NomeProduto + "', " +
                produto.QuantidadeMinima + ", " +
                produto.IDFornecedor + ", '" +               
                produto.PermitirEnvioEmail + "'," +
                produto.QuantidadePedido + "," +
                precoVenda + "," +
                0 + "," +
                0 + ")"; // 0 quer dizer que o produto cadastrado tem 0 unidades no estoque

            //Método que escreve o comando sql nos bancos de dados
            return controle.EscreveBancoDados(sql);

        }

        /// <summary>
        /// Recupera no banco todos os produtos cadastrados
        /// </summary>
        /// <returns>Lista com todos os produtos</returns>
        public List<Produto> RecuperarProdutos()
        {
            List<Produto> listaResposta = new List<Produto>();
            SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoServidor"].ConnectionString);
            SqlDataReader reader;
            //definição do comando sql
            string sql =
                "SELECT * FROM Produtos_Estoque";

            //Cria uma objeto do tipo comando passando como parametro a string sql e a string de conexão
            SqlCommand comando = new SqlCommand(sql, con);

            //--------tenta conectar no servidor externo-----------------------
            try
            {

                //abre a conexao
                con.Open();

                //Verifica se tem algum comando nao executado no servidor principal
                controle.verificaConsistencia();
                controle.verificaConsistenciaLocal();


                //executa a query
                reader = comando.ExecuteReader();

                //le os dados retornados e monta objeto Produto
                listaResposta = ListarProdutos(reader);

                //fecha a conexao
                con.Close();


            }

     //--------Ocorreu excessao, conectar no servidor local-------------------------
            catch (SqlException e)
            {


                //erro referente a servidor inacessivel ou timeout ocorreu
                if (e.Number == 53 || e.Number == -2)
                {
                    //configura para apontar no servidor local
                    SqlConnection con2 = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoLocal"].ConnectionString);
                    comando.Connection = con2;

                    //abre conexao
                    con2.Open();

                    //executa a query
                    reader = comando.ExecuteReader();

                    //le os dados retornados e monta objeto Produto
                    listaResposta = ListarProdutos(reader);

                    //fecha a conexao
                    con2.Close();

                }
            }
            finally
            {
                con.Close();
            }

            return listaResposta;


        }

         /// <summary>
        /// Edita um produto nos bancos de dados
        /// </summary>
        /// <param name="CPF">nome do produto a ser editado</param>
        /// <param name="produto">Novas caracteristicas do produto</param>
        /// <returns>true se editou ou false se não</returns>
        public bool EditarProduto(int ID, Produto produto)
        {
            //Converte o numero decimal de virgula para ponto
            string precoVenda = produto.PrecoVenda.ToString(CultureInfo.InvariantCulture);

            //definição do comando sql
            string sql =
                "UPDATE Produtos_Estoque SET " +
                "Nome = '" + produto.NomeProduto + "', " +
                "QntMinima = " + produto.QuantidadeMinima + ", " +
                "IDFornecedor = " + produto.IDFornecedor + ", " +
                "PermitirEmail = '" + produto.PermitirEnvioEmail + "', " +
                "QntPedido = " + produto.QuantidadePedido + ", " +
                "PrecoVenda = " + precoVenda + " WHERE ID =" + ID + "";

            //Método que escreve o comando sql nos bancos de dados
            return controle.EscreveBancoDados(sql);

        }
        


        /// <summary>
        /// Recupera um produto especifico do banco de dados
        /// </summary>
        /// <param name="nome">nome do produto que deseja recuperar</param>
        /// <returns>Entidade do produto recuperado</returns>
        public Produto RecuperarDetalhesProduto(int ID)
        {
            Produto resposta = null;
            SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoServidor"].ConnectionString);
            SqlDataReader reader;
            //definição do comando sql
            string sql =
                "SELECT * FROM Produtos_Estoque WHERE ID = " + ID + "";

            //Cria uma objeto do tipo comando passando como parametro a string sql e a string de conexão
            SqlCommand comando = new SqlCommand(sql, con);

            //--------tenta conectar no servidor externo-----------------------
            try
            {

                //abre a conexao
                con.Open();

                //Verifica se tem algum comando nao executado no servidor principal
                controle.verificaConsistencia();
                controle.verificaConsistenciaLocal();

                //executa a query
                reader = comando.ExecuteReader();

                //le os dados retornados e monta objeto funcionario
                resposta = ListarProdutos(reader).FirstOrDefault();

                //fecha a conexao
                con.Close();


            }
            //--------Ocorreu excessao, conectar no servidor local-------------------------
            catch (SqlException e)
            {
                //erro referente a servidor inacessivel ou timeout ocorreu
                if (e.Number == 53 || e.Number == -2)
                {
                    //configura para apontar no servidor local
                    SqlConnection con2 = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoLocal"].ConnectionString);
                    comando.Connection = con2;

                    //abre conexao
                    con2.Open();

                    //executa a query
                    reader = comando.ExecuteReader();
                    //le os dados retornados e monta objeto produto


                    //le os dados retornados e monta objeto produto
                    resposta = ListarProdutos(reader).FirstOrDefault();


                    //fecha a conexao
                    con2.Close();
                }

            }
            finally
            {
                con.Close();
            }

            return resposta;


        }


        /// <summary>
        /// Lê dados da tabela correspondente através de um comando SQL os montando a lista que é retornada
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        public List<Produto> ListarProdutos(SqlDataReader reader)
        {
            List<Produto> listaResposta = new List<Produto>();

            //le os dados retornados e monta objeto produto
            while (reader.Read())
            {
                listaResposta.Add(new Produto()
                {
                    ID = Convert.ToInt32(reader["ID"]),
                    NomeProduto = Convert.ToString(reader["Nome"]),
                    QuantidadeMinima = Convert.ToInt32(reader["QntMinima"]),
                    IDFornecedor = Convert.ToInt32(reader["IDFornecedor"]),
                    PermitirEnvioEmail = Convert.ToBoolean(reader["PermitirEmail"]),
                    QuantidadePedido = Convert.ToInt32(reader["QntPedido"]), 
                    PrecoVenda = Convert.ToDouble(reader["PrecoVenda"]),
                    SolicitacaoEnviada = Convert.ToBoolean(reader["SolicitacaoEnviada"])

                });

            }
            return listaResposta;


        }

        /// <summary>
        /// Cria o comando SQL e envia para um método excluir um produto dos bancos de dados
        /// </summary>
        /// <param name="apartamento">nome do produto</param>
        /// <returns>true se excluiu ou false se não</returns>
        public bool ExcluirProduto(int ID)
        {
            //definição do comando sql
            string sql =
                "DELETE FROM Produtos_Estoque WHERE ID = " + ID + "";

            //Método que escreve o comando sql nos bancos de dados
            return controle.EscreveBancoDados(sql);

        }
       
    }
}